﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace GLSimulationControl
{
    public class PinnedObject<T> where T:struct
    {
        protected T managedObject;
        protected GCHandle handle;
        protected IntPtr ptr;
        public bool disposed { get; protected set; }

        public T ManangedObject
        {
            get
            {
                return (T)handle.Target;
            }
            set
            {
                Marshal.StructureToPtr(value, ptr, false);
            }
        }

        public IntPtr Pointer
        {
            get { return ptr; }
        }

        public PinnedObject()
        {
            handle = GCHandle.Alloc(managedObject, GCHandleType.Pinned);
            ptr = handle.AddrOfPinnedObject();
        }

        ~PinnedObject()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (!disposed)
            {
                handle.Free();
                ptr = IntPtr.Zero;
                if (managedObject is IDisposable)
                    (managedObject as IDisposable).Dispose();
                disposed = true;
            }
        }
    }
}
